using System;
using System.Collections;
using System.Data;
using System.Runtime.CompilerServices;
using Dimok.Data.Database;

namespace Dimok.Data{

	////////////////////////////////////////////////////////////////////////////////////////////////////
	/// <summary>	Information base. </summary>
	///
	/// <remarks>	Dimon, 12/21/2010. </remarks>
	////////////////////////////////////////////////////////////////////////////////////////////////////

	public abstract class InfoBase{
		protected UserObjectEx uox;
		protected int ApplID;
		protected string db;
		protected string dbADO;
		protected DataSet _ds;

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>	Constructor. </summary>
		///
		/// <remarks>	Dimon, 12/21/2010. </remarks>
		///
		/// <param name="applID">	Identifier for the appl. </param>
		////////////////////////////////////////////////////////////////////////////////////////////////////

		public InfoBase(int applID) { ApplID = applID; }

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>	Constructor. </summary>
		///
		/// <remarks>	Dimon, 12/21/2010. </remarks>
		///
		/// <param name="uox">	The uox. </param>
		////////////////////////////////////////////////////////////////////////////////////////////////////

		public InfoBase(UserObjectEx uox){
			this.uox = uox;
			db = uox.db;
			dbADO = uox.dbADO;
			ApplID = uox.ApplID0;
		}

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>	Gets the sql v. </summary>
		///
		/// <value>	The sql v. </value>
		////////////////////////////////////////////////////////////////////////////////////////////////////

		public abstract string SQL_V{get;}

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>	Gets the sql u. </summary>
		///
		/// <value>	The sql u. </value>
		////////////////////////////////////////////////////////////////////////////////////////////////////

		public abstract string SQL_U{get;}

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>	Ds error. </summary>
		///
		/// <param name="rowCount">	Number of rows. </param>
		///
		/// <returns>	. </returns>
		////////////////////////////////////////////////////////////////////////////////////////////////////

		protected virtual string DS_Error(int rowCount){
			return "Information has "+rowCount+" rows.";
		}

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>	Resets the ds. </summary>
		////////////////////////////////////////////////////////////////////////////////////////////////////

		public virtual void ResetDS(){ _ds = null; }

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>	Gets the ds. </summary>
		///
		/// <returns>	. </returns>
		////////////////////////////////////////////////////////////////////////////////////////////////////

		public virtual DataSet DS(){
			if( _ds == null ){
				_ds = SQLHelperEx.ExecuteDatasetEx(uox.db,SQL_V);
				DataRow dr = Row;
			}
			return _ds;
		}

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>	Updates this object. </summary>
		///
		/// <param name="fieldName">	Name of the field. </param>
		/// <param name="fieldValue">	The field value. </param>
		////////////////////////////////////////////////////////////////////////////////////////////////////

		public virtual void Update(string fieldName,string fieldValue){
			uox.LockApplicant();
			SQLHelperEx.UpdateField(uox.db,SQL_U,fieldName,fieldValue);
		}

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>	Gets the row. </summary>
		///
		/// <value>	The row. </value>
		////////////////////////////////////////////////////////////////////////////////////////////////////

		public DataRow Row{
			get{
				DataRowCollection rows = DS().Tables[0].Rows;
				if( rows.Count != 1 )throw new Exception(DS_Error(rows.Count));
				return rows[0];
			}
		}

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>	Gets the xml. </summary>
		///
		/// <returns>	The xml. </returns>
		////////////////////////////////////////////////////////////////////////////////////////////////////

		public string GetXml(){ return DS().GetXml(); }

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>	Gets the xml inner text. </summary>
		///
		/// <returns>	. </returns>
		////////////////////////////////////////////////////////////////////////////////////////////////////

		public string XmlInnerText(){ return SQLHelperEx.XmlInnerText(DS()); }

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>	Gets the xml inner text. </summary>
		///
		/// <param name="addEmpty">	true to add empty. </param>
		///
		/// <returns>	. </returns>
		////////////////////////////////////////////////////////////////////////////////////////////////////

		public string XmlInnerText(bool addEmpty){ return SQLHelperEx.XmlInnerText(DS(),addEmpty); }

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>	Gets the get. </summary>
		///
		/// <returns>	. </returns>
		////////////////////////////////////////////////////////////////////////////////////////////////////

		[MethodImplAttribute(MethodImplOptions.NoInlining)]
		protected object Get(){return Get(Common.GetFuncName(1));}

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>	Gets the get. </summary>
		///
		/// <param name="name">	The string to get. </param>
		///
		/// <returns>	. </returns>
		////////////////////////////////////////////////////////////////////////////////////////////////////

		public virtual object Get(string name){return Row[name];}

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>	Gets the string. </summary>
		///
		/// <returns>	The string. </returns>
		////////////////////////////////////////////////////////////////////////////////////////////////////

		[MethodImplAttribute(MethodImplOptions.NoInlining)]
		protected string GetString(){return GetString(Common.GetFuncName(1));}

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>	Gets the string. </summary>
		///
		/// <param name="name">	The string to get. </param>
		///
		/// <returns>	The string. </returns>
		////////////////////////////////////////////////////////////////////////////////////////////////////

		public virtual string GetString(string name){return Get(name)+"";}

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>	Gets the int. </summary>
		///
		/// <returns>	The int. </returns>
		////////////////////////////////////////////////////////////////////////////////////////////////////

		[MethodImplAttribute(MethodImplOptions.NoInlining)]
		protected int GetInt(){return GetInt(Common.GetFuncName(1));}

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>	Gets the int. </summary>
		///
		/// <param name="name">	The string to get. </param>
		///
		/// <returns>	The int. </returns>
		////////////////////////////////////////////////////////////////////////////////////////////////////

		public virtual int GetInt(string name){
			object o = Get(name);
			return Dimok.Common.IsNumeric(o) ? int.Parse(o+"") : 0;
		}
	}

	#region InfoBaseDataSource Class

	////////////////////////////////////////////////////////////////////////////////////////////////////
	/// <summary>	Information base data source. </summary>
	///
	/// <remarks>	Dimon, 12/21/2010. </remarks>
	////////////////////////////////////////////////////////////////////////////////////////////////////

	public abstract class InfoBaseDataSource : InfoBase {
		protected DataRow _row = null;

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>	Gets the keys. </summary>
		///
		/// <value>	The keys. </value>
		////////////////////////////////////////////////////////////////////////////////////////////////////

		protected abstract IDictionary Keys { get; }
		protected Data.DataSources.AObjectDataSourceBase _dsObject = null;

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>	Gets the ds object. </summary>
		///
		/// <value>	The ds object. </value>
		////////////////////////////////////////////////////////////////////////////////////////////////////

		protected abstract Data.DataSources.AObjectDataSourceBase DSObject { get; }

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>	Constructor. </summary>
		///
		/// <remarks>	Dimon, 12/21/2010. </remarks>
		///
		/// <param name="applID">	Identifier for the appl. </param>
		////////////////////////////////////////////////////////////////////////////////////////////////////

		public InfoBaseDataSource(int applID) : base(applID) { }

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>	Constructor. </summary>
		///
		/// <remarks>	Dimon, 12/21/2010. </remarks>
		///
		/// <param name="uox">	The uox. </param>
		////////////////////////////////////////////////////////////////////////////////////////////////////

		public InfoBaseDataSource(UserObjectEx uox) : base(uox) { }

		#region DS
		DataSet _ds;

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>	Gets the ds. </summary>
		///
		/// <returns>	. </returns>
		////////////////////////////////////////////////////////////////////////////////////////////////////

		public override DataSet DS() { return DS(false); }

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>	Gets the ds. </summary>
		///
		/// <param name="refresh">	true to refresh. </param>
		///
		/// <returns>	. </returns>
		////////////////////////////////////////////////////////////////////////////////////////////////////

		public DataSet DS(bool refresh) {
			if (_ds == null || refresh) {
				Dimok.Data.Database.KeysFilter kf = new Dimok.Data.Database.KeysFilter(Keys);
				_ds = DSObject.Select(kf.Filter, kf.Params).Table.DataSet;
				DataRow dr = Row;
			}
			return _ds;
		}
		#endregion

		#region Update

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>	Updates this object. </summary>
		///
		/// <param name="fieldName">	Name of the field. </param>
		/// <param name="fieldValue">	The field value. </param>
		///
		/// <returns>	. </returns>
		////////////////////////////////////////////////////////////////////////////////////////////////////

		public new DataTable Update(string fieldName, string fieldValue) { return Update(fieldName, fieldValue, false); }

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>	Updates this object. </summary>
		///
		/// <param name="fieldName">		Name of the field. </param>
		/// <param name="fieldValue">		The field value. </param>
		/// <param name="returnResult">	true to return result. </param>
		///
		/// <returns>	. </returns>
		////////////////////////////////////////////////////////////////////////////////////////////////////

		public DataTable Update(string fieldName, string fieldValue, bool returnResult) {
			return DSObject.UpdateField(Keys, fieldName, fieldValue, returnResult);
		}
		#endregion

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>	Gets the sql v. </summary>
		///
		/// <value>	The sql v. </value>
		////////////////////////////////////////////////////////////////////////////////////////////////////

		public override string SQL_V { get { throw new NotImplementedException(); } }

		////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>	Gets the sql u. </summary>
		///
		/// <value>	The sql u. </value>
		////////////////////////////////////////////////////////////////////////////////////////////////////

		public override string SQL_U { get { throw new NotImplementedException(); } }
	}
	#endregion

}
